#include "h_stm32_hal_spi_norflash.h"
#include "h_stm32_hal_defines.h"
#include <stdio.h>
#include <stdlib.h>


#include "h_stm32_hal_uart.h"
//////////////////////////////////////////////////////////////////////////////////
#define NORFLASH_SPI		hspi1
extern SPI_HandleTypeDef 	NORFLASH_SPI;

#define NOR_FLASH_SECTOR_CHECK_BUF_SIZE		16
//////////////////////////////////////////////////////////////////////////////////

NorFlash_Handle norflash;

// static unsigned char *norflash_temp = NULL;

void H_STM32_SPI1_Select(void)
{
	HAL_GPIO_WritePin(SPI_NSS_GPIO_Port, SPI_NSS_Pin, GPIO_PIN_RESET);
}

void H_STM32_SPI1_DeSelect(void)
{
	HAL_GPIO_WritePin(SPI_NSS_GPIO_Port, SPI_NSS_Pin, GPIO_PIN_SET);
}

NorFlash_Result H_STM32_SPI1_Write(const unsigned char *data, unsigned short len)
{
	return (NorFlash_Result)HAL_SPI_Transmit(&NORFLASH_SPI, (unsigned char *)data, len, 0xFFFF);
}

NorFlash_Result H_STM32_SPI1_Read(unsigned char *data, unsigned short len)
{
	return (NorFlash_Result)HAL_SPI_Receive(&NORFLASH_SPI, data, len, 0xFFFF);
}
//////////////////////////////////////////////////////////////////////////////////

signed char H_STM32_SPI1_ReadSectors(unsigned int sector_num, unsigned short sector_count, unsigned char *buf)
{
	unsigned short i = 0U;

	NorFlash_Result rslt = norflash_OK;

	if(NULL == buf)
	{
		printf("read buff null\r\n");
		return -1;
	}

	for(; i < sector_count; i ++)
	{
		// printf("--reading...\r\n");
		// printf("--read addr :%d\r\n", sector_num * norflash.sectorSize);
		rslt = S_NorFlash_Read(norflash, sector_num * norflash.sectorSize, buf, norflash.sectorSize);

		// printf("--read finished\r\n");
		sector_num++;
		if(norflash_OK != rslt)
		{
			break;
		}
	}

	return rslt;
	
}


signed char H_STM32_SPI1_WriteSectors(unsigned int sector_num, unsigned short sector_count, unsigned char *buf)
{
	unsigned short i = 0U;

	NorFlash_Result rslt = norflash_OK;

	for(; i < sector_count; i ++)
	{
		// printf("--writing...\r\n");
		// printf("--write addr :%d\r\n", sector_num * norflash.sectorSize);
		// if(h_stm32_spi1_checksectors(sector_num))
		// {
		// 	H_STM32_SPI1_ReadSectors();
		// }
		// printf("--ready to erasing...\n");
		rslt = S_NorFlash_Erase(norflash, sector_num * norflash.sectorSize, norflash.sectorSize);
		// printf("--erase finished\r\n");

		rslt = S_NorFlash_Write(norflash, sector_num * norflash.sectorSize, buf, norflash.sectorSize);
		// debug_hex(buf, norflash.sectorSize);
		// printf("--write finished\r\n");
		sector_num++;
		if(norflash_OK != rslt)
		{
			break;
		}
	}

	return rslt;
	
}


signed char h_stm32_spi_norFlash_init(void)
{
	signed char rslt = 0;

	norflash.manId = 0xEF;
	norflash.devId = 0x14;
	norflash.devSize = 2097152; //16Mb
	norflash.sectorCount = 256;//512;//512;
	norflash.pageSize = 256;
	norflash.sectorSize = 4096;//4096;
	norflash.blockSize = 1;//65536;

	norflash.norflash_select = &H_STM32_SPI1_Select;
	norflash.norflash_deselect = &H_STM32_SPI1_DeSelect;
	norflash.norflash_write = &H_STM32_SPI1_Write;
	norflash.norflash_read = &H_STM32_SPI1_Read;

	rslt = S_NorFlash_Open(norflash);
	rslt += S_NorFlash_Close(norflash);
	return 0;
}

signed char h_stm32_spi_norFlash_open(void)
{
	S_NorFlash_Open(norflash);
	return 0;
}

signed char h_stm32_spi_norFlash_close(void)
{
	S_NorFlash_Close(norflash);
	return 0;
}

signed char h_stm32_spi_norFlash_eraseChip(void)
{
	return S_NorFlash_ChipErase(norflash);
}

signed char h_stm32_spi_norFlash_erasePage(unsigned short page)
{
	return S_NorFlash_Erase(norflash, FLASH_ADDRESS(page,0), norflash.sectorSize);
}

signed char h_stm32_spi_norFlash_read(unsigned int offset, unsigned char *data, unsigned short len)
{
	return S_NorFlash_Read(norflash, offset, data, len);;
}

signed char h_stm32_spi_norFlash_write(unsigned int offset, const unsigned char *data, unsigned short len)
{
	return S_NorFlash_Write(norflash, offset, data, len);;
}

signed char h_stm32_spi_norFlash_readSectors(unsigned int sector_num, unsigned short sector_count, unsigned char *buf)
{
	unsigned short i = 0U;

	NorFlash_Result rslt = norflash_OK;

	if(NULL == buf) {
		printf("read buff null\r\n");
		return -1;
	}

	for(; i < sector_count; i ++) {
		rslt = S_NorFlash_Read(norflash, sector_num * norflash.sectorSize, buf, norflash.sectorSize);
		sector_num++;
		if(norflash_OK != rslt) {
			break;
		}
	}

	return rslt;
	
}

signed char h_stm32_spi_norFlash_writeSectors(unsigned int sector_num, unsigned short sector_count, unsigned char *buf)
{
	unsigned short i = 0U;

	NorFlash_Result rslt = norflash_OK;

	for(; i < sector_count; i ++) {
		rslt = S_NorFlash_Erase(norflash, sector_num * norflash.sectorSize, norflash.sectorSize);
		rslt = S_NorFlash_Write(norflash, sector_num * norflash.sectorSize, buf, norflash.sectorSize);
		sector_num++;
		if(norflash_OK != rslt) {
			break;
		}
	}

	return rslt;
	
}